package model.time;

import java.util.Calendar;


/**
 * Objects of this class are intended to represent a specific day of the week repetition  
 * within a dateStart and a dateEnd.
 * @author estoll
 *
 */


public class WeeklyTimeFrame extends TimeFrame {
	// Structure

	/**
	 * Constructs a WeeklyTimeFrame object validating possible Exceptions.
	 * @param dateStart GregorianCalendar
	 * @param dateEnd GregorianCalendar
	 * @param t	GregorianCalendar, default date values 1900.01.01, only time values are significant
	 * @param t1 GregorianCalendar, default date values 1900.01.01, only time values are significant
	 * @param dayName String day
	 * @throws NullParametersReceivedExpeption Is thrown if any of the needed parameters are null
	 * @throws InvalidMinutesException Is thrown if the minute field of the time values are not 00 or 30
	 * @throws IllegalTimeValuesException Is thrown if timeEnd <= timeStart
	 */
	public WeeklyTimeFrame(Calendar dateStart, Calendar dateEnd,
			Calendar timeStart, Calendar timeEnd, String dayName)
			throws NullParametersReceivedExpeption, InvalidMinutesException,
			IllegalTimeValuesException {

		if ((dateStart != null) && (dateEnd != null) && (dayName != null)
				&& (timeStart != null) && (timeEnd != null)) {
			{
				if (((timeStart.get(Calendar.MINUTE) == 30) || (timeStart
						.get(Calendar.MINUTE) == 00))
						&& ((timeEnd.get(Calendar.MINUTE) == 30) || (timeEnd
								.get(Calendar.MINUTE) == 00))) {
					if ((timeStart.equals(timeEnd))
							|| (timeEnd.before(timeStart))) {
						throw new IllegalTimeValuesException();
					} else {
						this.setDateStart(dateStart);
						this.setDateEnd(dateEnd);
						this.setTimeStart(timeStart);
						this.setTimeEnd(timeEnd);
						this.setDayName(dayName);
					}
				} else {
					throw new InvalidMinutesException();
				}
			}
		} else {
			throw new NullParametersReceivedExpeption();
		}
	}

	public WeeklyTimeFrame() {
		// TODO Auto-generated constructor stub
		super();
	}

	public String getType(){
		return "Weekly";
	}
	
	
	
	/**
	 * Double Dispatching Calls the method isOverlappedFromWeeklyTimeFrame of
	 * the SingleTimeFrame class, passing this as parameter.
	 * @param withThisObject SingleTimeFrame
	 * @return Boolean
	 */
	public boolean isOverlapped(SingleTimeFrame withThisObject) {
		return (withThisObject.isOverlappedFromWeeklyTimeFrame(this));
	}

	/**
	 * Double Dispatching Calls the method isOverlappedFromWeeklyTimeFrame of
	 * the DailyTimeFrame class, passing this as parameter.
	 * @param withThisObject DailyTimeFrame
	 * @return Boolean
	 */
	public boolean isOverlapped(DailyTimeFrame withThisObject) {
		return (withThisObject.isOverlappedFromWeeklyTimeFrame(this));
	}

	/**
	 * Double Dispatching Calls the method isOverlappedFromWeeklyTimeFrame of
	 * the WeeklyTimeFrame class, passing this as parameter.
	 * @param withThisObject WeeklyTimeFrame
	 * @return Boolean
	 */
	public boolean isOverlapped(WeeklyTimeFrame withThisObject) {
		return (withThisObject.isOverlappedFromWeeklyTimeFrame(this));
	}

	/**
	 * Double Dispatching Calls the method isOverlappedFromWeeklyTimeFrame of
	 * the MonthlyTimeFrame class, passing this as parameter.
	 * @param withThisObject MonthlyTimeFrame
	 * @return Boolean
	 */
	public boolean isOverlapped(MonthlyTimeFrame withThisObject) {
		return (withThisObject.isOverlappedFromWeeklyTimeFrame(this));
	}

	/**
	 * Answers a remote Calls from a Double Dispatch from the WeeklyTimeFrame class.
	 * @param withThisObject WeeklyTimeFrame
	 * @return Boolean
	 */
	public boolean isOverlappedFromWeeklyTimeFrame(WeeklyTimeFrame his) {
		return (
		(this.getDayName().equals(his.getDayName()) && (this
				.dateRangeIsOverlapped(his))) &&
		(this.timeIsOverlapped(his)));
	}

	/**
	 * Answers a remote Calls from a Double Dispatch from the DailyTimeFrame class.
	 * @param withThisObject DailyTimeFrame
	 * @return Boolean
	 */
	public boolean isOverlappedFromDailyTimeFrame(DailyTimeFrame his) {
		return (
		(this.dateRangeIsOverlapped(his)) &&
		(this.timeIsOverlapped(his))
		);
	}

	/**
	 * Answers a remote Calls from a Double Dispatch from the SingleTimeFrame class.
	 * @param withThisObject SingleTimeFrame
	 * @return Boolean
	 */
	public boolean isOverlappedFromSingleTimeFrame(SingleTimeFrame his) {
		return (
		((this.getDayName().equals(his.getDayName())) && (his
				.singleDayIsOverlapped(this))) &&
		(this.timeIsOverlapped(his)));
	}

	/**
	 * Answers a remote Calls from a Double Dispatch from the MonthlyTimeFrame class.
	 * @param withThisObject MonthlyTimeFrame
	 * @return Boolean
	 */
	public boolean isOverlappedFromMonthlyTimeFrame(MonthlyTimeFrame his) {
		return ((
		(this.getDayName().equals(his.getDayName()))
		&& (this.dateRangeIsOverlapped(his))) &&
		(this.timeIsOverlapped(his)));
	}

}
